package gpstools.data;

import gpstools.track.Track;
import gpstools.track.TrackPoint;
import gpstools.util.FileName;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Track loader that can choose the specific loader by the file extension
 * 
 * @author Marcin Skruch
 */
public class TrackLoader implements TrackSource {
    private static Map<String, Loader> loaders = new HashMap<String, Loader>();
    private final TrackSource source;

    static {
        register(new TcxLoader());
        register(new GpxLoader());
        register(new FitLoader());
    }

    private static void register(Loader loader) {
        loaders.put(loader.getExtension(), loader);
    }

    public TrackLoader(String fileName) throws IOException, UnsupportedFormatException {
        Loader loader = resolveLoader(fileName);
        source = loader.load(fileName);
    }

    private Loader resolveLoader(String fileName) throws UnsupportedFormatException {
        String extension = new FileName(fileName).extension();
        Loader loader = TrackLoader.loaders.get(extension);
        if (loader == null) {
            throw new UnsupportedFormatException("unsupported extension: " + extension);
        }
        return loader;
    }
    
    public TrackLoader(String fileName, byte[] data) throws UnsupportedFormatException{
        Loader loader = resolveLoader(fileName);
        source = loader.load(data);
    }

    @Override
    public Track next() {
        return source.next();
    }
    
    public List<TrackPoint> getPoints() {
        List<TrackPoint> points = new ArrayList<TrackPoint>();
        Track track;

        while ((track = next()) != null) {
            points.addAll(track.getPoints());
        }
        return points;
    }
    
    public TrackPoint[] getPointsArray(){
        List<TrackPoint> points = getPoints();
        return points.toArray(new TrackPoint[points.size()]);
    }

}
